/**
 * <pre>
 * @(#)ScalarView.java 1.00 2009-11-6
 * 
 * Copyright (c) 1998, 2009 Regular Individual. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * Contributor(s):
 *     Haixu Huang
 * </pre>
 **/
package cn.sh.huang.chart.view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;

import cn.sh.huang.chart.config.ChartConfig;
import cn.sh.huang.chart.data.Argument;
import cn.sh.huang.chart.data.DataSeries;
import cn.sh.huang.chart.data.DataTable;
import cn.sh.huang.chart.data.Variable;
import cn.sh.huang.chart.ext.enumtype.Amplitude;
import cn.sh.huang.chart.ext.enumtype.ChartType;

/**
 * <pre>
 * ScalarView ...
 * 
 * @version 1.0
 * </pre>
 */
public class ScalarView extends ChartView
{
    private static final int MIN_DATA_WIDTH = 11; // 2 + 7 + 2
    private final ChartConfig config = new ChartConfig(this);

    public ScalarView()
    {
        this(ChartType.SCALAR_VERT);
    }

    public ScalarView(ChartType type)
    {
        if (!type.equals(ChartType.SCALAR_VERT) && !type.equals(ChartType.SCALAR_HORZ)) {
            throw new IllegalArgumentException("!ERROR! Wrong ChartType parameter.");
        }
        config.setType(type);
    }

    private Dimension getScalarViewSize(boolean isPreferred)
    {
        int w = MINIMUM_VIEW_WIDTH, h = MINIMUM_VIEW_WIDTH;
        if (data != null) {
            ChartType type = config.getType();
            int fontHeight = DEFAULT_CANVAS.getFontMetrics(config.getFont()).getHeight();
            int argLen = data.getArguments().length, serLen = data.getSeriez().length;
            if (type.equals(ChartType.SCALAR_VERT)) { // ��ֱ
                w = isPreferred ? argLen * serLen * MIN_DATA_WIDTH : MINIMUM_VIEW_WIDTH;
                h = 120 + fontHeight + 14; // + 14 for scroll bar
            } else { // ˮƽ
                w = 120 + 60 + 14; // + 60 for label; + 14 for scroll bar
                h = isPreferred ? argLen * Math.max(serLen * MIN_DATA_WIDTH, fontHeight * 2) : MINIMUM_VIEW_WIDTH;
            }
        }
        return new Dimension(w, h);
    }

    public Dimension getPreferredSize()
    {
        return getScalarViewSize(true);
    }

    public Dimension getMinimumSize()
    {
        return getScalarViewSize(false);
    }

    protected boolean validateData(DataTable _data)
    {
        // TODO Auto-generated method stub
        return true;
    }

    void setDataShape()
    {
        DataSeries[] serz = data.getSeriez();
        Argument[] args = data.getArguments();
        ChartType type = config.getType();
        Amplitude amp = config.getAmplitude();
        Dimension viewSize = getViewSize();
        double shift = 0, step =
            (type.equals(ChartType.SCALAR_VERT) ? viewSize.getWidth() : viewSize.getHeight()) / args.length;
        int w = (int) (step / serz.length) - 2;
        int maxAmp = type.equals(ChartType.SCALAR_VERT) ? viewSize.height : viewSize.width;
        for (int i = 0; i < serz.length; i++, shift += step / serz.length) {
            DataSeries ser = serz[i];
            for (int j = 0; j < args.length; j++) {
                Argument arg = args[j];
                Variable var = data.getVariable(ser, arg);
                Integer h = amp.getAmplitude(ser.toNomalizedValue(var.getData()), maxAmp);
                if (h != null) {
                    Rectangle rect = new Rectangle();
                    if (type.equals(ChartType.SCALAR_VERT)) {
                        rect.width = w;
                        rect.height = h.intValue();
                        rect.x = (int) Math.round(step * j + shift);
                        rect.y = maxAmp - rect.height;
                    } else {
                        rect.height = w;
                        rect.width = h.intValue();
                        rect.y = viewSize.height - (int) Math.round(step * j + shift) - w;
                        rect.x = 0;
                    }
                    var.setShape(rect);
                }
            }
        }
    }

    void drawDataShape(Graphics2D g2d)
    {
        g2d.setColor(getBgColor());
        g2d.fill(new Rectangle(new Point(0, 0), getViewSize()));
        g2d.setColor(Color.BLACK);
        DataSeries[] serz = data.getSeriez();
        Argument[] args = data.getArguments();
        for (int i = 0; i < serz.length; i++) {
            DataSeries ser = serz[i];
            for (int j = 0; j < args.length; j++) {
                Argument arg = args[j];
                Variable var = data.getVariable(ser, arg);
                g2d.draw(var.getShape());
            }
        }
    }
}
